<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>设计模式——组合模式</title>
    <script type="application/javascript" charset="UTF-8">
        // 组合模式
        /**
         * 场景模拟 (树状结构——Tree)
         * 公司
         *      -> 财务部门
         *                  ->张一
         *                  ->张二
         *                  ->张三
         *      -> 销售部门
         *                  ->张五
         *                  ->张六
         *  实际的人是具体到人身上的，只有人才有具体方法的实现
         */
        // 公司
        var Org = function (name) {
            // 公司名称
            this.name = name;
            // 公司部门
            this.depts = [];
        };

        // 公司应该具有的方法
        Org.prototype = {
            constructor : Org,
            /**
             * 添加部门
             * @param child 部门名称
             */
            addDepts : function (child) {
                this.depts.push(child);
                return this;
            },
            /**
             * 获取该公司的部门
             * @returns {Array}
             */
            getDepts : function () {
                return this.depts;
            }
        };

        // 部门
        var Dept = function (name) {
            // 部门名称
            this.name = name;
            // 部门员工
            this.persons = [];
        };

        // 部门应该有的方法
        Dept.prototype = {
            constructor : Dept,
            /**
             * 添加员工
             * @param child
             * @returns {Dept}
             */
            addPersons : function (child) {
                this.persons.push(child);
                return this;
            },
            /**
             * 获取部门员工
             * @returns {Array}
             */
            getPersons : function () {
                return this.persons;
            }
        };

        // 员工
        var Person = function (name) {
            this.name = name;
        };

        // 员工应该有的方法
        Person.prototype  = {
            constructor : Person,
            /**
             * 员工努力工作
             */
            hardWorking : function () {
                alert(this.name + ' 努力工作!');
            },
            /**
             * 员工好好休息
             */
            sleeping : function () {
                alert(this.name + '好好休息');
            }
        };

        // 结构公司组织关系
        var org = new Org('boqii');
        var dept1 = new Dept('develop');
        var dept2 = new Dept('HR');
        org.addDepts(dept1).addDepts(dept2);
        var p1 = new Person('张1');
        var p2 = new Person('张2');
        var p3 = new Person('张3');
        var p4 = new Person('张4');
        dept1.addPersons(p1).addPersons(p2);
        dept2.addPersons(p3).addPersons(p4);

        // 需求 ： 让某一个人（'张3'）努力工作
        for (var i = 0, depts = org.getDepts(); i < depts.length; i++) {  // 循环公司部门
            for (var j = 0, persons = depts[i].getPersons(); j < persons.length; j++) {  // 循环部门员工
                if (persons[j].name === '张3') {
                    persons[j].hardWorking();
                }
            }
        }

        // 上边的代码，显然是存在问题的
        // 如果需求改变，是让某一整个部门都努力工作
        // 显然是需要改变代码的，最后随着需求的不断改变，会造成代码的冗余
        // 解决方法见 design_composite_02.html


    </script>
</head>
<body>

</body>
</html>